import Plotly from 'plotly.js-dist-min';

// === 1) 解析：把三元组转成数值数组 ===
function parseTriples(triples) {
    const xs = [], ys = [], zs = [];
    for (const t of triples) {
        const x = Number(t[0]);   // 你数据里是字符串，转 number
        const y = Number(t[1]);
        const z = Number(t[2]);
        if (Number.isFinite(x) && Number.isFinite(y) && Number.isFinite(z)) {
            xs.push(x); ys.push(y); zs.push(z);
        }
    }
    return { xs, ys, zs };
}

// === 2) 生成规则网格 ===
function makeGrid(xs, ys, nx = 120, ny = 120) {
    const xmin = Math.min(...xs), xmax = Math.max(...xs);
    const ymin = Math.min(...ys), ymax = Math.max(...ys);
    const xg = Array.from({ length: nx }, (_, j) => xmin + (j * (xmax - xmin)) / (nx - 1));
    const yg = Array.from({ length: ny }, (_, i) => ymin + (i * (ymax - ymin)) / (ny - 1));
    return { xg, yg };
}

// === 3) 简单 IDW 插值（反距离加权）===
// - p: 幂次（常用 2）
// - k: 每个网格点只取最近的 k 个邻居（加速 & 抗噪），k=16~32 一般够用
function idwGrid(xs, ys, zs, xg, yg, p = 2, k = 24) {
    const n = xs.length;
    // 预建索引（简单版：直接 O(n) 查最近邻；若要更快可以换 k-d 树）
    const Z = Array.from({ length: yg.length }, () => Array(xg.length).fill(0));

    for (let i = 0; i < yg.length; i++) {
        const y0 = yg[i];
        for (let j = 0; j < xg.length; j++) {
            const x0 = xg[j];

            // 找 k 个最近邻
            const dists = [];
            for (let t = 0; t < n; t++) {
                const dx = xs[t] - x0, dy = ys[t] - y0;
                const d2 = dx*dx + dy*dy;
                dists.push([d2, zs[t]]);
            }
            dists.sort((a, b) => a[0] - b[0]);
            const neigh = dists.slice(0, k);

            // 如果有一个点几乎重合，直接取它的值
            if (neigh[0][0] < 1e-12) { Z[i][j] = neigh[0][1]; continue; }

            // 按权重求和
            let num = 0, den = 0;
            for (const [d2, zv] of neigh) {
                const w = 1 / Math.pow(d2, p / 2); // (1 / d^p)
                num += w * zv;
                den += w;
            }
            Z[i][j] = num / den;
        }
    }
    return Z;
}

// === 4) 画等值线 ===
export function drawContourFromTriples(triples, dom) {
    const { xs, ys, zs } = parseTriples(triples);

    // 网格大小：可按图尺寸/性能调整（80~160 比较常用）
    const NX = 120, NY = 120;
    const { xg, yg } = makeGrid(xs, ys, NX, NY);

    const Zgrid = idwGrid(xs, ys, zs, xg, yg, 2, 24);

    const zMin = Math.min(...zs), zMax = Math.max(...zs);
    // 设定更干净的等值线级别（比如每 300 一条）
    const step = Math.max(1, Math.round((zMax - zMin) / 12 / 50)) * 50; // 约 12 条，每 50 的倍数

    const contour = {
        type: 'contour',
        x: xg,
        y: yg,
        z: Zgrid,
        colorscale: 'Viridis',           // 或 'Cividis'、'Turbo'、'Portland'
        contours: {
            coloring: 'fill',              // 填充颜色
            showlabels: true,              // 在线上标注 z 值
            labelfont: { size: 11, color: '#111' },
            start: Math.floor(zMin / step) * step,
            end: Math.ceil(zMax / step) * step,
            size: step
        },
        line: { smoothing: 0 },
        showscale: true,
        hovertemplate: 'x=%{x:.1f}<br>y=%{y:.1f}<br>z=%{z:.1f}<extra></extra>'
    };

    // 叠加原始散点（可选，便于比对）
    const scatter = {
        type: 'scattergl',
        mode: 'markers',
        x: xs,
        y: ys,
        marker: { size: 4, opacity: 0.6 },
        name: 'samples',
        hovertemplate: 'x=%{x}<br>y=%{y}<br>z=%{customdata}<extra></extra>',
        customdata: zs
    };

    Plotly.newPlot(dom, [contour, scatter], {
        title: 'Contour（IDW 插值后）',
        margin: { t: 40, l: 50, r: 40, b: 50 },
    }, { responsive: true });
}
